﻿#include<iostream>

using namespace std;

////基类
//class Person
//{
//public:
//	//基类的虚函数
//	virtual void buyticket() 
//	{
//		cout << "买票-全价" << endl; 
//	}
//};
//
////派生类
//class Student : public Person
//{
//public:
//	//派生类的虚函数重写了基类的虚函数
//	virtual void buyticket()
//	{ 
//		cout << "买票-打折" << endl;
//	}
//};
//
////派生类
//class Soldier : public Person
//{
//public:
//	//派生类的虚函数重写了基类的虚函数
//	virtual void buyticket()
//	{
//		cout << "优先-买票" << endl;
//	}
//};
//
//void Func(Person* ptr)
//{
//	// 这⾥可以看到虽然都是Person指针ptr在调⽤buyticket
//	// 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
//	ptr->buyticket();
//}
//
//void Func(Person& ptr)
//{
//	// 这⾥可以看到虽然都是Person的引用ptr在调⽤buyticket
//	// 但是跟ptr没关系，⽽是由ptr引用的对象决定的。
//	ptr.buyticket();
//}
//
//
//int main()
//{
//	Person ps;//普通人
//	Student st;//学生
//	Soldier sd;//军人
//
//	Func(&ps);//基类的指针调用虚函数
//	Func(&st);
//	Func(&sd);
//
//	Func(ps);//基类的引用调用虚函数
//	Func(st);
//	Func(sd);
//
//	return 0;
//}


//class Animal
//{
//public :
//	virtual void talk() const
//	{}
//};
//class Dog : public Animal
//{
//public :
//	virtual void talk() const
//	{
//		std::cout << "汪汪" << std::endl;
//	}
//};
//class Cat : public Animal
//	{
//	public :
//	virtual void talk() const
//	{
//	std::cout << "(>^ω^<)喵" << std::endl;
//	}
//};
//void letsHear(const Animal& animal)
//{
//	animal.talk();
//}
//
//int main()
//{
//	Cat cat;
//	Dog dog;
//	letsHear(cat);
//	letsHear(dog);
//	return 0;
//}

//class A
//{
//public :
//	virtual void func(int val = 1)
//	{
//		std::cout << "A->" << val << std::endl;
//	}
//	virtual void test() 
//	{
//		func(); 
//	}
//
//};
//
//class B : public A
//{
//public :
//	void func(int val = 0)
//	{
//		std::cout << "B->" << val << std::endl; 
//	}
//};
//
//int main(int argc, char* argv[])
//{
//	B* p = new B;
//    p->test();
//
//	return 0;
//}


//class A {};
//class B : public A {};
//
//class Person
//{
//public:
//	virtual A* BuyTicket()//基类虚函数返回基类对象的指针
//	{
//		cout << "买票-全价" << endl;
//		return nullptr;
//	}
//};
//class Student : public Person {
//public:
//	virtual B* BuyTicket()//派生类虚函数返回派生类对象的指针
//	{
//		cout << "买票-打折" << endl;
//		return nullptr;
//	}
//};
//void Func(Person* ptr)
//{
//	ptr->BuyTicket();
//}
//
//int main()
//{
//	Person ps;
//	Student st;
//
//	Func(&ps);//基类对象调用基类的虚函数
//	Func(&st);//派生类对象调用派生类的虚函数
//
//    return 0;
//}

//class A
//{
//public :
//	virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//
//class B : public A
//{
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//// 只有派⽣类Student的析构函数重写了Person的析构函数，下⾯的delete对象调⽤析构函数，才能
////构成多态，才能保证p1和p2指向的对象正确的调⽤析构函数。
//int main()
//{
//	A* p1 = new A;
//	A* p2 = new B;
//
//	delete p1;
//	delete p2;
//	return 0;
//}

//class Car
//{
//public:
//	virtual void Dirve() final
//	{}
//};
//
//class Benz :public Car
//{
//public:
//	virtual void Dirve() 
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//
//int main()
//{
//	return 0;
//}

////抽象类
//class Car
//{
//public :
//	virtual void Drive() = 0;//纯虚函数
//};
//
//class Benz :public Car
//{
//public:
//	virtual void Drive()//派生类重写虚函数
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//
//class BMW :public Car
//{
//public :
//	virtual void Drive()//派生类重新虚函数
//	{
//		cout << "BMW-操控" << endl;
//	}
//};
//
//int main()
//{
//
//	// 派生类重写了纯虚函数(f非抽象类)，可以实例化出对象
//	Benz b1;
//	BMW b2;
//
//	//不同对象用基类指针调用Drive函数，完成不同的行为
//	Car* p1 = &b1;
//	Car* p2 = &b2;//派生类可以赋值给基类的指针或引用
//	p1->Drive(); 
//	p2->Drive();  
//
//	return 0;
//}

//class Base
//{
//public :
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//protected:
//	int _b = 1;
//	char _ch = 'x';
//};
//
//int main()
//{
//	Base b;
//	cout << sizeof(b) << endl;
//	return 0;
//}


////父类
//class Base
//{
//public:
//	//虚函数
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	//虚函数
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//	//普通成员函数
//	void Func3()
//	{
//		cout << "Base::Func3()" << endl;
//	}
//private:
//	int _b = 1;
//};
////子类
//class Derive : public Base
//{
//public:
//	//重写虚函数Func1
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
//private:
//	int _d = 2;
//};

//class Base
//{
//public:
//	virtual void func1()
//	{ 
//		cout << "Base::func1" << endl;
//	}
//	virtual void func2() 
//	{
//		cout << "Base::func2" << endl;
//	}
//	void func5()
//	{ 
//		cout << "Base::func5" << endl;
//	}
//protected:
//	int a = 1;
//};
//
//class Derive : public Base
//{
//public :
//	// 重写基类的func1
//	virtual void func1()
//	{
//		cout << "Derive::func1" << endl;
//	}
//	virtual void func3()
//	{ 
//		cout << "Derive::func1" << endl; 
//	}
//	void func4()
//	{ 
//		cout << "Derive::func4" << endl; 
//	}
//protected:
//	int b = 2;
//};
//
//int main()
//{
//	int i = 0;
//	static int j = 1;
//	int* p1 = new int;
//	const char* p2 = "xxxxxxxx";
//	printf("栈:%p\n", &i);
//	printf("静态区:%p\n", &j);
//	printf("堆:%p\n", p1);
//	printf("常量区:%p\n", p2);
//	Base b;
//	Derive d;
//	Base* p3 = &b;
//	Derive* p4 = &d;
//	printf("Base虚表地址:%p\n", *(int*)p3);
//	printf("Derive虚表地址:%p\n", *(int*)p4);
//	printf("虚函数地址:%p\n", &Base::func1);
//	printf("普通函数地址:%p\n", &Base::func5);
//	return 0;
//}

//基类
class Person
{
public:
	//基类的虚函数
	virtual void buyticket()
	{
		cout << "买票-全价" << endl;
	}
private:
	string _name;
};

//派生类
class Student : public Person
{
public:
	//派生类的虚函数重写了基类的虚函数
	virtual void buyticket()
	{
		cout << "买票-打折" << endl;
	}
private:
	string _id;
};

//派生类
class Soldier : public Person
{
public:
	//派生类的虚函数重写了基类的虚函数
	virtual void buyticket()
	{
		cout << "优先-买票" << endl;
	}
private:
	string _codename;
};

void Func(Person* ptr)
{
	// 这⾥可以看到虽然都是Person指针ptr在调⽤buyticket
	// 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
	ptr->buyticket();
}


int main()
{
	
	Student st;
	Person* ps = &st;
	ps->buyticket();
	
	return 0;
}
